package com.myioc.myClassPathContext;


import MyDependence.MyDOA;
import com.myioc.myfilter.MyFilter;
import com.myioc.utils.ClassUtil;
import com.myioc.utils.StringUtil;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReferenceArray;

//手写SpringIOC注解版 类加载器
public class MyClassPathApplicationContext {
    private  String pakegeName;       //需要扫包的范围和包名
    private AtomicReferenceArray<String> atomicReferenceArray;     //原子类集合，用来拓展
    private static ConcurrentHashMap<String,Object> beans;    //并发Map集合，保证线程安全性

    public MyClassPathApplicationContext(String pakegeName,String[] strs) throws Exception {
        //参数初始化
        this.pakegeName=pakegeName;
        if (pakegeName==null||pakegeName.equals("")){
            throw new Exception("pakeheName is null");
        }
        atomicReferenceArray=new AtomicReferenceArray<String>(strs);
        beans=new ConcurrentHashMap<>();
        getMyBean();
    }

    public Object getBean(String beanId) throws Exception {
        if (StringUtils.isEmpty(beanId)){
            throw  new Exception("beanId is null");
        }
        Object object =beans.get(beanId);
        if (object==null){
            throw  new Exception("object not found");
        }
        //在初始化容器管理时，将其中属性也一并管理
        MyDOA.getProperty(object,beans);
        return object;
    }

    //初始化对象
    public Object newInstance(Class<?> classInfo)  {
        try { Object object=classInfo.newInstance();return object; }
        catch (Exception e) { e.printStackTrace();return null; }
    }

    public void getMyBean() throws Exception{
        /*
        反射获取该包的所有的类
        判断该类是否有自己定义的注解
        存在自定义注解，创建对象 用容器储存
        */
        List<Class<?>> classList=ClassUtil.getClasses(pakegeName);
        // 将类上有注解的Class 和类名提取出来
        ConcurrentHashMap<String, Object> classExisAnnotation=findClassExisAnnotation(classList);
        if (classExisAnnotation==null||classExisAnnotation.isEmpty()){
            throw  new Exception("Not Annotation");
        }

    }

    public ConcurrentHashMap<String, Object> findClassExisAnnotation(List<Class<?>> classList){
        classList.stream().filter(aClass -> {
            for (int i=0;i<atomicReferenceArray.length();i++){
                //判断该类的注解是否为参数数组atomicReferenceArray所包含的
                try {   if (aClass.getDeclaredAnnotation((Class<? extends Annotation>) Class.forName(atomicReferenceArray.get(i)))!=null){
                    return true;    }
                } catch (Exception e) { e.printStackTrace(); return false; }
            }
            return false;
        }).forEach(aClass -> beans.put(StringUtil.toLowerCaseFirstOne(aClass.getSimpleName()),this.newInstance(aClass)));
        return beans;
    }



}
